/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.yami.shop.bean.enums.CategoryLevel;
import com.yami.shop.bean.model.Category;
import com.yami.shop.bean.model.CategoryLang;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.PoiExcelUtil;
import com.yami.shop.dao.CategoryMapper;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author LGH
 */
@Slf4j
@Service
@AllArgsConstructor
public class CategoryExcelServiceImpl implements CategoryExcelService {

    private static final String PRIMARY_CATEGORY = "一级分类";
    private static final String SECONDARY_CATEGORY = "二级分类";
    private static final String TERTIARY_CATEGORY = "三级分类";
    private final CategoryMapper categoryMapper;


    @Override
    public void export(HttpServletResponse response, Long shopId) {
        // 获取导出的分类列表
        List<Category> categories = listCategoryAndLangList(shopId);
        // 存入excel中
        createExcel(categories, response, shopId);
    }


    private List<Category> listCategoryAndLangList(Long shopId) {
        List<Category> categories = categoryMapper.listCategoryAndLangList(shopId);
        if (CollUtil.isEmpty(categories)) {
            return new ArrayList<>();
        }
        for (Category category : categories) {
            // 处理国际化信息
            List<CategoryLang> categoryLangList = category.getCategoryLangList();
            for (CategoryLang categoryLang : categoryLangList) {
                if (Objects.equals(categoryLang.getLang(), LanguageEnum.LANGUAGE_EN.getLang())) {
                    category.setCategoryNameEn(categoryLang.getCategoryName());
                } else {
                    category.setCategoryName(categoryLang.getCategoryName());
                }
            }
        }
        return categories;
    }

    private void createExcel(List<Category> categories, HttpServletResponse response, Long shopId) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getBigWriter();
        // 商品导出or模板
        List<String> headerList = getHeaderList(shopId);
        Sheet sheet = getSheet(writer);

        writer.merge(headerList.size() - 1, Objects.equals(I18nMessage.getDbLang(), 0) ? "分类信息" : "Category Information");
        writer.writeRow(headerList);
        try {
            // excel下拉弹窗列表组装
            String[] categoryLevel = {PRIMARY_CATEGORY, SECONDARY_CATEGORY, TERTIARY_CATEGORY};
            PoiExcelUtil.createDropDownList(sheet, categoryLevel, 2, 50000, 3, 3);

            // 分类列表为空
            if (CollUtil.isEmpty(categories)) {
                PoiExcelUtil.writeExcel(response, writer);
                return;
            }

            Map<Long, List<Category>> categoryMap = categories.stream().filter(category -> Objects.nonNull(category.getParentId())).collect(Collectors.groupingBy(Category::getParentId));

            // 一级分类列表不存在
            if (Objects.isNull(categoryMap.get(0L))) {
                PoiExcelUtil.writeExcel(response, writer);
                return;
            }
            int row = 1;
            // 写入分类
            writeCategoryToExcel(categoryMap.get(0L), writer, row, "", categoryMap, shopId);

            PoiExcelUtil.writeExcel(response, writer);
        } catch (Exception e) {
            log.error("分类导出:", e);
            throw new YamiShopBindException(e.getMessage());
        }
    }

    private int writeCategoryToExcel(List<Category> categories,ExcelWriter writer, int row, String parentCategoryNames, Map<Long, List<Category>> categoryMap, Long shopId) {
        if (CollUtil.isEmpty(categories)) {
            return row;
        }
        for (Category category : categories) {
            int col = -1;

            // 写入分类数据
            PoiExcelUtil.mergeIfNeed(writer, ++row, row, ++col, col, category.getCategoryName());
            PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, category.getCategoryNameEn());

            // 平台端分类独有字段
            if (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
                String deductionRate = Objects.equals(category.getGrade(), CategoryLevel.THIRD.value()) ? category.getDeductionRate().toString() : "";
                String categoryGrade = PRIMARY_CATEGORY;
                if (Objects.equals(category.getGrade(), CategoryLevel.SECOND.value())) {
                    categoryGrade = SECONDARY_CATEGORY;
                } else if (Objects.equals(category.getGrade(), CategoryLevel.THIRD.value())) {
                    categoryGrade = TERTIARY_CATEGORY;
                }

                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, deductionRate);
                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, categoryGrade);
                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, parentCategoryNames);
            }
            if (categoryMap.containsKey(category.getCategoryId())) {
                // 写入该分类的下级分类
                String parentNames = parentCategoryNames.length() == 0 ?category.getCategoryName():parentCategoryNames + "/" + category.getCategoryName();
                row = writeCategoryToExcel(categoryMap.get(category.getCategoryId()), writer, row, parentNames, categoryMap, shopId);
            }
        }
        return row;
    }

    @NotNull
    private List<String> getHeaderList(Long shopId) {
        List<String> headerList;
        if (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
            String[] headerCn = {"中文分类名称", "英文分类名称", "分类扣率", "分类层级", "父级分类（格式：一级分类/二级分类，中文名称）"};
            String[] headerEn = {"Chinese category Name", "English category Name", "Category deduction rate", "Category parent（Chinese Name）", "Category grade"};
            headerList = Arrays.asList(Objects.equals(I18nMessage.getDbLang(), 0) ? headerCn : headerEn);
        } else {
            String[] headerCn = {"*中文分类名称", "英文分类名称"};
            String[] headerEn = {"Chinese category Name", "English category Name"};
            headerList = Arrays.asList(Objects.equals(I18nMessage.getDbLang(), 0) ? headerCn : headerEn);
        }
        return headerList;
    }

    @NotNull
    private Sheet getSheet(ExcelWriter writer) {
        Sheet sheet = writer.getSheet();
        sheet.setColumnWidth(0, 60 * 256);
        sheet.setColumnWidth(1, 60 * 256);
        sheet.setColumnWidth(2, 20 * 256);
        sheet.setColumnWidth(3, 20 * 256);
        sheet.setColumnWidth(4, 60 * 256);
        return sheet;
    }

}
